#ifndef DHWL_SOCKET_SOCKET_M_H
#define DHWL_SOCKET_SOCKET_M_H

#include "global.h"
extern "C" {
    #include <stdint.h>
    #include <time.h>
}

#include <map>
#include <bitset>
#include <vector>
#include <list>
#include "exception/SocketException.h"

#define LISTENQ 1024 //监听队列数量
#define ACTIVE_TIMEOUT  300 //心跳超时时间
#define HEAR_CHECK_TIMEOUT  60 //心跳检查时间
#define IO_BUFF_MAX_SIZE    8192
#define DATA_RESET_MAX_OFFSET    8192

namespace ZY {
 //   class SockIO;
    class Sock;


}

#include "Event.h"
//#include "SockIO.h"
//#include "CmdExec.h"
//#include "interface/IUserData.h"
//


namespace ZY {

    class SocketEpoll ;


    class Sock : public EventBase
    {
        public:
            //const static int EVENT_CLOSE;
            const static int EVENT_INIT;
            const static int EVENT_DESTORY;
            const static int EVENT_ACCPET;
            const static int EVENT_WRITE_EMPTY;

            Sock() :
                fd(0) , //io(NULL) ,
                write_data( _writeByteStringObject.getDataStringQuote() ) ,
                write_data_offset( _writeByteStringObject.getDataStringReadOffsetQuote() )
                {this->_Sock( AF_INET,SOCK_STREAM,0 );}

            Sock( int _domain , int _type , int _protocol ) :
                fd(0) , //io (NULL) ,
                write_data( _writeByteStringObject.getDataStringQuote() ) ,
                write_data_offset( _writeByteStringObject.getDataStringReadOffsetQuote() )
                {this->_Sock( _domain , _type , _protocol );}

            Sock( int i_fd ) ;
            Sock(bool);
            virtual ~Sock();

            static Sock& getStaticSock();

            bool ConnectDomain( string domain , in_port_t port );
            bool Connect( string ip , in_port_t port );
            bool bindAndListen( in_port_t port );
            bool bindAndListen( in_port_t port , uint16_t listenq );
            int getFd() const{return fd;};
            void setNonblock(){fcntl( fd, F_SETFL, O_NONBLOCK);};
            void Accept() ;
            Sock *getSelfPointer() {return this;};
            void setActive() { lastActiveTime = time(NULL);}
            void setActive( time_t t ) { lastActiveTime = t;}
            time_t getActive() { return lastActiveTime;}
            void setStatus( uint8_t bitNumber , bool flg ) { status[bitNumber] = (flg ? 1 : 0);}
            bool getStatus( uint8_t bitNumber ) {return (bool) status[bitNumber];}
            bool Close();
            bool _Close();
//            void NewIO( SocketEpoll &s );
//            void DeleteIO();
//            SockIO &IO(){return *io;}
            //CmdExec *cmd(){return m_cmd;}
            void setUserData( void *p ) { _userData = p;}
            void *getUserData() {return _userData;}
            bool isAccepted() { return status[2] ? true: false;}
            bool isConnected() { return status[1] ? true : false; }
            bool isLocked();
            bool lockSocket();
            bool unlockSocket();
            bool needDelete();
            bool readAll();
            bool writeAll();

            void send();
            void send( ByteString &bs);
            void send( ByteString *bs) {send( *bs );};

            ByteString &getReadByteStringObject();
            ByteString &getWriteByteStringObject();

            void nativeSend( ByteString &bs) {string str( bs.getDataString()  );nativeSend(str);}
            void nativeSend( string &str );
            void nativeSend( string *str ) { nativeSend(*str);}
            void nativeSend( ByteString *bs) { nativeSend(*bs);}

            ///事件相关,可以注册存在的事件
//            static void event_register( int event_code , void(*func)(Sock&) ) ;
//            static void event_unregister( int event_code );
//            static bool event_exists( int event_code ) ;

            static Sock *getPointer( int i_fd );
            static void heartCheck( int activeTimeout );
            static void heartCheck();

            static void CloseListCheck();

        protected:

            int fd;
            time_t lastActiveTime;
            bitset<8> status;
            /*
                0 : 表明listen
                1 : 表明connect
                2 : 是否需要心跳检查
                3 : 正在读取
                4 : 正在写入
                5 : 表明是正在关闭状态(禁止收发数据)
                6: 可以释放
                7:阻塞状态，等待解锁定

            */


            void _Sock( int _domain , int _type , int _protocol );
            static map<int,Sock *> m_map;
            static list<Sock *> m_close_list;
        private:
//            SockIO *io;
            //SocketEpoll &se;
            //CmdExec *m_cmd;
            static time_t _heartCheckTime;
            bool _needDelete;

            void *_userData;
//            static map<int, void(*)( Sock &)> m_events;

            //读缓冲区
            ByteString _readByteStringObject ;
            //写缓冲区
            ByteString _writeByteStringObject;

            char readbuff[IO_BUFF_MAX_SIZE];
            char writebuff[IO_BUFF_MAX_SIZE];

            string & write_data;
            unsigned & write_data_offset;
    };

};
#endif // SOCKET_H
